<script setup lang="ts">
import { reactive, watch, ref } from 'vue'
import { useI18n } from 'vue-i18n'
import { storeToRefs } from 'pinia'
import {
  PanelLeftExpand20Filled,
  PanelLeftContract20Filled,
  ChatMultiple24Regular,
} from '@vicons/fluent'
import { Icon } from '@vicons/utils'
import { useChatStore } from '@/stores/chat'
import $config from '@/config'
import { isMobileMode } from '@/utils/detection'
import ChatHistory from '@/components/chat/ChatHistory.vue'

const { t } = useI18n()

// 聊天存储
const chatStore = useChatStore()
const { readConvsHistory, readActiveConvKey } = storeToRefs(chatStore)

// 展开状态
const modelExpand = defineModel('expand', { type: Boolean, required: true })

// 状态参数
const state = reactive({
  // 侧边栏是否收缩
  isSidebarCollapsed: false,
  // 侧边栏 mask 是否隐藏
  isHideSidebarMask: false,
})

// 组件
const chatHistoryRef = ref()

// 伸缩侧边栏
const troggerSidebar = () => {
  modelExpand.value = !modelExpand.value
}

// 切换对话
const onChangeConv = (key: string) => {
  chatStore.changeActiveConvId(key)
  if (isMobileMode()) {
    modelExpand.value = false
  }
}

// 置顶对话
const onTopConv = async (key: string, isTop: boolean) => {
  await chatStore.setConvInfo(key, { isTop })
}

// 重命名对话
const onRenameConv = async ({ key, title }) => {
  await chatStore.setConvInfo(key, { title })
}

// 删除对话
const onRemoveConv = async (key: string) => {
  await chatStore.delConvInfo(key)
}

// 监听双向绑定
watch(
  () => modelExpand.value,
  async (isExpand) => {
    state.isSidebarCollapsed = !isExpand
    if (isExpand) {
      await new Promise((resolve) => setTimeout(resolve, 300)) // Delay to match transition
      state.isHideSidebarMask = true
    } else {
      state.isHideSidebarMask = false
    }
  },
  {
    immediate: true,
  },
)

defineExpose({
  troggerSidebar,
})
</script>

<template>
  <div
    class="side-panel-mask"
    @click="troggerSidebar"
    :class="{ off: state.isSidebarCollapsed, hide: state.isSidebarCollapsed }"
  ></div>
  <div class="side-panel" :class="{ off: state.isSidebarCollapsed }">
    <div class="title">
      <div class="name">{{ $config.title }}</div>
      <div class="collapsed" @click="troggerSidebar">
        <a-tooltip :title="t('system.collapseSidebar')" placement="right">
          <Icon size="24px" class="icon close">
            <PanelLeftContract20Filled />
          </Icon>
        </a-tooltip>
        <a-tooltip :title="t('system.expandSidebar')" placement="right">
          <Icon size="24px" class="icon open">
            <PanelLeftExpand20Filled />
          </Icon>
        </a-tooltip>
      </div>
    </div>
    <div class="action" @click="onChangeConv('')">
      <n-button class="btn-open" strong secondary block type="primary">
        <template #icon>
          <Icon size="24px">
            <ChatMultiple24Regular />
          </Icon>
        </template>
        {{ t('chat.conversation.startNew') }}
      </n-button>
      <a-tooltip :title="t('chat.conversation.startNew')" placement="right">
        <n-button class="btn-close" text type="primary">
          <Icon size="24px" class="btn-close">
            <ChatMultiple24Regular />
          </Icon>
        </n-button>
      </a-tooltip>
    </div>
    <n-scrollbar class="history">
      <ChatHistory
        ref="chatHistoryRef"
        :options="readConvsHistory"
        :active-key="readActiveConvKey"
        @change="onChangeConv"
        @top="onTopConv($event, true)"
        @untop="onTopConv($event, false)"
        @rename="onRenameConv"
        @delete="onRemoveConv"
      />
    </n-scrollbar>
  </div>
</template>

<style lang="scss" scoped>
.side-panel {
  display: flex;
  flex-direction: column;
  width: 280px;
  background-color: var(--vas-sidebar-bg);
  transition: width 0.3s;
  .title {
    display: flex;
    align-items: center;
    padding: 18px 15px;
    justify-content: space-between;
    .name {
      font-size: 18px;
      color: var(--vas-title-color);
      margin-right: 10px;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
    .collapsed {
      cursor: pointer;
      .icon {
        color: var(--vas-text-color);
        &.close {
          display: block;
        }
        &.open {
          display: none;
        }
      }
    }
  }
  .action {
    font-size: 24px;
    padding: 0 15px;
    color: #aaa;
    display: flex;
    justify-content: center;
    .btn-open {
      display: flex;
      cursor: pointer;
    }
    .btn-close {
      display: none;
      cursor: pointer;
    }
  }
  :deep(.history) {
    margin: 10px 0;
    .ant-conversations {
      overflow-x: hidden;
    }
  }
  &.off {
    width: 60px;
    .title {
      justify-content: center;
      .name {
        display: none;
      }
      .collapsed {
        .icon {
          &.close {
            display: none;
          }
          &.open {
            display: block;
          }
        }
      }
    }
    .action {
      .btn-open {
        display: none;
      }
      .btn-close {
        display: block;
      }
    }
    :deep(.history) {
      display: none;
    }
  }
}
@media (max-width: 767px) {
  .side-panel {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 70vw;
    z-index: 999;
    overflow: hidden;
    transition: transform 0.3s;
    &.off {
      width: 70vw;
      transform: translateX(-100%);
      .title {
        justify-content: space-between;
        .name {
          display: block;
        }
      }
      .action {
        .btn-open {
          display: flex;
        }
        .btn-close {
          display: none;
        }
      }
      .scrollable-container {
        display: block;
      }
    }
  }
  .side-panel-mask {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    opacity: 0.6;
    background-color: rgba(0, 0, 0, 0.45);
    z-index: 998;
    transition: opacity 0.3s;
    &.off {
      opacity: 0;
    }
    &.hide {
      display: none;
    }
  }
}
</style>
